package com.imc.platform.base.user.security;

/**
 * Created by tanweiping on 2018/7/20.
 */

import com.imc.platform.base.menu.pojo.Menu;
import com.imc.platform.base.menu.service.impl.MenuServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/*
 * 类描述：访问决策管理器
 * 开发者：tanweiping
 * 创建日期：2018/8/7 10:33
 */
/**
 * Created by yangyibo on 17/1/19.
 */
@Slf4j
@Service
public class MyAccessDecisionManager implements AccessDecisionManager {


    @Autowired
    MenuServiceImpl menuServiceImpl;

    /*
     * tanweiping  2018/8/7 10:34
     * 方法描述：
     *  decide 方法是判定是否拥有权限的决策方法，
     *  authentication 是释CustomUserService中循环添加到 GrantedAuthority 对象中的权限信息集合.
     *  object 包含客户端发起的请求的requset信息，可转换为 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();
     *  configAttributes 为MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法返回的结果，此方法是为了判定用户请求的url 是否在权限表中，如果在权限表中，则返回给 decide 方法，用来判定用户是否有此权限。如果不在权限表中则放行。
     */
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        FilterInvocation fi = ((FilterInvocation) object);
        HttpServletRequest request = fi.getHttpRequest();

        if(null== configAttributes || configAttributes.size() <=0) {
            return;
        }
        ConfigAttribute c;
        String needRole;
        for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
            c = iter.next();
            needRole = c.getAttribute();
            for(GrantedAuthority ga : authentication.getAuthorities()) {
                //authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合
                if(needRole.trim().equals(ga.getAuthority())) {
                    if (request.getAttribute("menuList")==null && request.getAttribute("currentMenu")==null){
                        String[]parmUrl= fi.getRequestUrl().split("\\?");
                        List<Menu> menuList = menuServiceImpl.getMenuByMenuUrl(parmUrl[0]);

                        //不带参数
                        if(parmUrl.length==1){
                            for(int i=0;i<menuList.size();i++){
                                menuList.get(i).setMenuUrl(menuList.get(i).getMenuUrl()+"?menuId="+menuList.get(0).getId());
                            }
//                            if(1==menuList.size()){
//                                menuList.get(0).setMenuUrl(menuList.get(0).getMenuUrl()+"?menuId="+menuList.get(0).getId());
//                            }else if(2 == menuList.size()){
//                                menuList.get(0).setMenuUrl(menuList.get(0).getMenuUrl()+"?menuId="+menuList.get(0).getId());
//                                menuList.get(1).setMenuUrl(menuList.get(1).getMenuUrl()+"?menuId="+menuList.get(1).getId());
//                            }else if(3 == menuList.size()){
//                                menuList.get(0).setMenuUrl(menuList.get(0).getMenuUrl()+"?menuId="+menuList.get(0).getId());
//                                menuList.get(1).setMenuUrl(menuList.get(1).getMenuUrl()+"?menuId="+menuList.get(1).getId());
//                                menuList.get(1).setMenuUrl(menuList.get(2).getMenuUrl()+"?menuId="+menuList.get(2).getId());
//                            }
                        } else if(parmUrl.length == 2){
                            String backParms="";
                            for(int i=0;i<menuList.size();i++){
                                if(parmUrl[1].contains("menuId")){
                                    backParms="?"+parmUrl[1];
                                }else {
                                    backParms ="?"+parmUrl[1]+"&menuId="+menuList.get(i).getId();
                                }
                                if(!"".equals(menuList.get(i).getMenuUrl()) && null != menuList.get(i).getMenuUrl()){
                                    menuList.get(i).setMenuUrl(menuList.get(i).getMenuUrl()+backParms);
                                }else {
                                    menuList.get(i).setMenuUrl("/home/index");
                                }

                            }
                        }
                        if (!menuList.isEmpty()){
                            request.setAttribute("menuList",menuList);
                            request.setAttribute("currentMenu",menuList.get(menuList.size()-1));
                        }
                    }
                    return;
                }
            }
        }
        throw new AccessDeniedException("no right");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}